package date;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Arrays;
import java.util.GregorianCalendar;
import java.util.List;

/*
  @Author 12618
 * @Date 2022/5/17 14:19
 * @Version 1.0
 */

/**
 * 给出日期，计算下一天.
 *
 * @author 12618
 */
public class NextDate {
  /**
   * 小月：4，6，9，11.
   */
  /* default */ private List<Integer> smallMonth = Arrays.asList(4, 6, 9, 11);

  /**
   * 一年有12个月份.
   */
  /* default */ private List<Integer> everyMonth =
      Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
  /**
   * 一个月最多有31天.
   */
  /* default */ private List<Integer> everyDay = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
      11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31);
  /**
   * length of string.
   */
  /* default */ public static final int LENGTH_OF_STRING = 3;
  /**
   * month in February.
   */
  /* default */ public static final int MONTH_IN_FEBRUARY = 2;
  /**
   * 日期错误信息.
   */
  /* default */ public static final String WARNING = "日期输入错误";
  /**
   * 日期错误信息.
   */
  /* default */ private String string = "我是一条提示";
  /**
   * 实例化一个公历日历.
   */
  /* default */ private final GregorianCalendar calendar = new GregorianCalendar();

  /**
   * 区分2月，大小月，12月最后一天的nextDate.
   *
   * @param getLine the get line
   * @return string string
   */
  public String nextDate(final String getLine) {
    final String[] str = getLine.replaceAll("[\\u4e00-\\u9fa5]", " ").split(" ");
    if (str.length < LENGTH_OF_STRING) {
      string = WARNING;
      return string;
    }
    final int year = Integer.parseInt(str[0]);
    final int month = Integer.parseInt(str[1]);
    final int day = Integer.parseInt(str[2]);
    if (month == MONTH_IN_FEBRUARY) {
      int check = 28;
      if (calendar.isLeapYear(year)) {
        check = 29;
      }
      string = getDate(year, month, day, check);
    } else if (smallMonth.contains(month)) {
      string = getDate(year, month, day, 30);
    } else {
      string = getDate(year, month, day, 31);
    }
    final boolean right = checkYear(year) && everyMonth.contains(month) && everyDay.contains(day);
    return right ? string : WARNING;
  }

  /**
   * 根据大小月和日期，计算下一天.
   *
   * @param getYear  年
   * @param getMonth 月
   * @param check    month是否溢出
   * @return 下一天 date
   */
  public String getDate(final int getYear, final int getMonth, final int getDay, final int check) {
    int year = getYear;
    int month = getMonth;
    final int temp = getMonth;
    int day = getDay;
    month += day / check;
    day += 1 - check * (day / check);
    year += month / 12;
    month = month - 12 * (month / 12);
    final boolean right = month - temp >= 1 && day != 1;
    return right ? WARNING : year + "年" + month + "月" + day + "日";
  }

  /**
   * 是否在1964到2050年内.
   *
   * @param year 年
   * @return boolean boolean
   */
  public boolean checkYear(final int year) {
    return year >= 1964 && year <= 2050;
  }

  /**
   * Gets small month.
   *
   * @return the small month
   */
  @SuppressFBWarnings("EI_EXPOSE_REP")
  public List<Integer> getSmallMonth() {
    return smallMonth;
  }

  /**
   * Sets small month.
   *
   * @param smallMonth the small month
   */
  @SuppressFBWarnings("EI_EXPOSE_REP2")
  public void setSmallMonth(final List<Integer> smallMonth) {
    this.smallMonth = smallMonth;
  }

  /**
   * Gets every month.
   *
   * @return the every month
   */
  @SuppressFBWarnings("EI_EXPOSE_REP")
  public List<Integer> getEveryMonth() {
    return everyMonth;
  }

  /**
   * Sets every month.
   *
   * @param everyMonth the every month
   */
  @SuppressFBWarnings("EI_EXPOSE_REP2")
  public void setEveryMonth(final List<Integer> everyMonth) {
    this.everyMonth = everyMonth;
  }

  /**
   * Gets every day.
   *
   * @return the everyday
   */
  @SuppressFBWarnings("EI_EXPOSE_REP")
  public List<Integer> getEveryDay() {
    return everyDay;
  }

  /**
   * Sets every day.
   *
   * @param everyDay the everyday
   */
  @SuppressFBWarnings("EI_EXPOSE_REP2")
  public void setEveryDay(final List<Integer> everyDay) {
    this.everyDay = everyDay;
  }

  /**
   * Gets calendar.
   *
   * @return the calendar
   */
  @SuppressFBWarnings("EI_EXPOSE_REP")
  public GregorianCalendar getCalendar() {
    return calendar;
  }

  /**
   * Gets string.
   *
   * @return the string
   */
  public String getString() {
    return string;
  }

  /**
   * Sets string.
   *
   * @param string the string
   */
  public void setString(final String string) {
    this.string = string;
  }
}


